package com.flyee.viewer.ui.realty.listpanorama
{
	import com.flyee.utils.load.StackLoader;
	import com.flyee.utils.load.model.LoaderModel;
	import com.flyee.utils.load.processor.LoadLevelType;
	import com.flyee.utils.load.processor.LoadReturnType;
	
	import flash.display.Bitmap;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.events.ProgressEvent;
	import flash.geom.Point;
	
	import mx.controls.ProgressBar;
	import mx.core.UIComponent;
	import mx.managers.PopUpManager;
	
	import org.papervision3d.cameras.Camera3D;
	import org.papervision3d.materials.BitmapMaterial;
	import org.papervision3d.materials.utils.MaterialsList;
	import org.papervision3d.objects.DisplayObject3D;
	import org.papervision3d.objects.primitives.Cube;
	import org.papervision3d.render.BasicRenderEngine;
	import org.papervision3d.scenes.Scene3D;
	import org.papervision3d.view.Viewport3D;

	public class ListPanoramaManager extends UIComponent
	{
		static public var SCREEN_WIDTH  :int = 623;
		static public var SCREEN_HEIGHT :int = 465;
		
		
		public static const BITMAP_FRONT:String = "front";
		public static const BITMAP_BACK:String = "back";
		public static const BITMAP_RIGHT:String = "right";
		public static const BITMAP_LEFT:String = "left";
		public static const BITMAP_TOP:String = "top";
		public static const BITMAP_BOTTOM:String = "bottom";
		
		
		// ___________________________________________________________________ 3D vars

		private var container :Viewport3D;
		private var scene     :Scene3D;
		private var cube:Cube = null;
		private var camera    :Camera3D
		private var renderer  :BasicRenderEngine;
		private var complexObject:DisplayObject3D = null;
		private var soucePoint:Point = new Point();
		
		private var configXML:XML = null;

		private var type:String = null;

		private var parentSprite:Sprite = null;
		
		private var bitmapArray:Array = new Array();
		private var mapLoader:LoaderModel = null;
		private var needMap:Boolean = false;
		
		private var progressWindow:ProgressBar = null;
		
		public static const WINDOW_WIDTH:uint = 420;
		public static const WINDOW_HEIGHT:uint = 320;
		
		public function ListPanoramaManager(type:String,parentSprite:Sprite,myXML:XML,needMap:Boolean = false)
		{
			this.needMap = needMap;
			this.parentSprite = parentSprite;
			initPanorama(type,myXML)
		}
		public function initPanorama(type:String,myXML:XML):void
		{
			
			container = new Viewport3D(SCREEN_WIDTH,SCREEN_HEIGHT);

			// Create scene
			scene = new Scene3D();

			// Create camera
			camera = new Camera3D();
			
			renderer = new BasicRenderEngine();
			camera.zoom = 1;
			camera.focus = 500;
			camera.z = 0;
			
			this.getloaderList(myXML,type);
		}
		private var tatolCount:uint = 7;
		private var nowCount:uint = 0;
		private function getloaderList(myXML:XML,type:String):void
		{
			var tempObj:Object = {dir:BITMAP_FRONT,dirCount:0}	
			var imgLoader:StackLoader = new StackLoader();
			imgLoader.load(Constants.STATIC_SERVER+"/"+myXML.children()[type].front,
			LoadLevelType.LV_1,progressHandle,getBitmap,LoadReturnType.RETURN_LOADER,tempObj);
			
			var tempObj2:Object = {dir:BITMAP_BACK,dirCount:1}	
			var imgLoader2:StackLoader = new StackLoader();
			imgLoader2.load(Constants.STATIC_SERVER+"/"+myXML.children()[type].back,
			LoadLevelType.LV_1,progressHandle,getBitmap,LoadReturnType.RETURN_LOADER,tempObj2);
			
			var tempObj3:Object = {dir:BITMAP_RIGHT,dirCount:2}	
			var imgLoader3:StackLoader = new StackLoader();
			imgLoader3.load(Constants.STATIC_SERVER+"/"+myXML.children()[type].right,
			LoadLevelType.LV_1,progressHandle,getBitmap,LoadReturnType.RETURN_LOADER,tempObj3);
			
			var tempObj4:Object = {dir:BITMAP_LEFT,dirCount:3}	
			var imgLoader4:StackLoader = new StackLoader();
			imgLoader4.load(Constants.STATIC_SERVER+"/"+myXML.children()[type].left,
			LoadLevelType.LV_1,progressHandle,getBitmap,LoadReturnType.RETURN_LOADER,tempObj4);
			
			var tempObj5:Object = {dir:BITMAP_TOP,dirCount:4}	
			var imgLoader5:StackLoader = new StackLoader();
			imgLoader5.load(Constants.STATIC_SERVER+"/"+myXML.children()[type].up,
			LoadLevelType.LV_1,progressHandle,getBitmap,LoadReturnType.RETURN_LOADER,tempObj5);
			
			var tempObj6:Object = {dir:BITMAP_BOTTOM,dirCount:5}	
			var imgLoader6:StackLoader = new StackLoader();
			imgLoader6.load(Constants.STATIC_SERVER+"/"+myXML.children()[type].down,
			LoadLevelType.LV_1,progressHandle,getBitmap,LoadReturnType.RETURN_LOADER,tempObj6);
			
			var tempObj7:Object = {dir:"map",dirCount:6}	
			var imgLoader7:StackLoader = new StackLoader();
			imgLoader7.load(Constants.STATIC_SERVER+"/"+myXML.children()[type].map,
			LoadLevelType.LV_1,progressHandle,this.getMap,LoadReturnType.RETURN_LOADER,tempObj7);
		}
		private function progressHandle(e:ProgressEvent):void
		{
			if(this.progressWindow == null)
			{
				this.progressWindow = new ProgressBar()
				PopUpManager.addPopUp(this.progressWindow,this.parent);
				PopUpManager.centerPopUp(this.progressWindow)
			}
			var per:String = Math.round(e.bytesLoaded / e.bytesTotal *100) +"%"
			this.progressWindow.label = "加载中 （"+"资源"+"   "+ (this.nowCount+1)+"/"+(this.tatolCount)+"  "+per+")";
		}
		public function getBitmap(tagContainer:LoaderModel):void
		{
			this.nowCount +=1;
			this.bitmapArray[tagContainer.memo.dirCount] = tagContainer;
			if(this.nowCount == this.tatolCount)
			{
				creatPanorama()
			}
		}
		public function getMap(tagContainer:LoaderModel):void
		{
			this.nowCount +=1;
			mapLoader = tagContainer;
			this.parentSprite.addChild(mapLoader);
			mapLoader.mouseChildren = false;
			mapLoader.mouseEnabled = false;
			mapLoader.x = -430
			mapLoader.y = 0
			
			if(this.nowCount == this.tatolCount)
			{
				creatPanorama()
			}
		}
		private function creatPanorama():void
		{
			if(!needMap)
			{
				mapLoader.visible = false;
			}
			if(this.progressWindow)
			{
				PopUpManager.removePopUp(this.progressWindow);
				this.progressWindow = null;
			}
			
			init3D();
		
			createCube();
			
			this.name = "360MC"
			this.addEventListener(MouseEvent.MOUSE_DOWN,downHnadle);
			this.parentSprite.addEventListener(MouseEvent.MOUSE_UP,upHnadle);
			this.parentSprite.addEventListener(MouseEvent.MOUSE_WHEEL,wheelHnadle);
			renderer.renderScene(scene,camera,container)
		}
		private function downHnadle(event:MouseEvent):void
		{
			if(!this.parentSprite.hasEventListener(MouseEvent.MOUSE_MOVE))
			{
				this.parentSprite.addEventListener(MouseEvent.MOUSE_MOVE, loop );
				soucePoint.x = this.mouseX;
				soucePoint.y = this.mouseY;
			}
		}
		private function upHnadle(event:MouseEvent):void
		{
			if(this.parentSprite.hasEventListener(MouseEvent.MOUSE_MOVE))
			{
				this.parentSprite.removeEventListener( MouseEvent.MOUSE_MOVE, loop );
			}
		}
		private function wheelHnadle(event:MouseEvent):void
		{
			if(event.delta > 0 )
			{
				camera.focus += 10;
				
			}
			else
			{
				camera.focus -= 10
				
			}
			update3D()
		}
			// ___________________________________________________________________ Init3D

		private function init3D():void
		{
			// Create container sprite and center it in the stage
			this.addChild( container );
			container.x = 0;
			container.y = 0;
			
		}
		// ___________________________________________________________________ Create Cube
	
		private function createCube():void
		{
			// Attributes
			var size :Number = 5000;
			var quality :Number = 20;
	
			// Materials

			var materials:MaterialsList = new MaterialsList(
			{
				//all:
				front:  new BitmapMaterial( (this.bitmapArray[0].content as Bitmap).bitmapData ),
				back:   new BitmapMaterial( (this.bitmapArray[1].content as Bitmap).bitmapData  ),
				right:  new BitmapMaterial( (this.bitmapArray[2].content as Bitmap).bitmapData ),
				left:   new BitmapMaterial( (this.bitmapArray[3].content as Bitmap).bitmapData ),
				top:    new BitmapMaterial( (this.bitmapArray[4].content as Bitmap).bitmapData  ),
				bottom: new BitmapMaterial( (this.bitmapArray[5].content as Bitmap).bitmapData  )
			} );
			// Cube face settings
			// You can add or sustract faces to your selection. For examples: Cube.FRONT+Cube.BACK or Cube.ALL-Cube.Top.

			// On single sided materials, all faces will be visible from the inside.
			var insideFaces  :int = Cube.ALL;

			// Front and back cube faces will not be created.
			var excludeFaces :int = Cube.NONE;

			// Create the cube.
			cube = new Cube( materials, size, size, size, quality, quality, quality, insideFaces, excludeFaces );
	
			scene.addChild( cube, "Cube" );
			update3D();
		}


		// ___________________________________________________________________ Loop

		private function loop(event:MouseEvent):void
		{
			var tempAddX:Number = this.mouseX - soucePoint.x;
			soucePoint.x = this.mouseX;
			var tempAddY:Number = this.mouseY - soucePoint.y;
			soucePoint.y = this.mouseY
			
			
			if(this.mouseX < this.soucePoint.x)
			{
				tempAddX = tempAddX/3;
			}
			if(this.mouseY < this.soucePoint.y)
			{
				tempAddY = tempAddY/3;
			}
			setCameraMove(tempAddX,tempAddY)
		}

		public function setCameraMove(tagX:Number,tagY:Number):void
		{
			excursionX = tagX;
			excursionY = tagY;
			update3D();
		}
		public function setCameraFouce(tagNumber:Number):void
		{
			camera.focus += tagNumber;
			update3D();
		}
		public function setCameraToLine():void
		{
			if(camera.rotationX != 0)
			{
				if(Math.abs(camera.rotationX -baseAdd) < baseAdd)
				{
					setCameraMove(baseAdd, - camera.rotationX)

				}
				else
				{
					if(camera.rotationX > 0)
					{
						setCameraMove(baseAdd, - baseAdd)
					}
					else
					{
						setCameraMove(baseAdd, baseAdd)
					}
				}
			}
			else
			{
				setCameraMove(baseAdd, 0)
			}
		}
		private var excursionX:Number = 0;
		private var excursionY:Number = 0;
		private var baseAdd:int = 1;
		private function update3D():void
		{
			
			// Pan
			camera.rotationY += excursionX;

			// Tilt
			
			camera.rotationX += excursionY;
			
			excursionX = 0;
			excursionY = 0;
			
			if(camera.rotationX >90)
			{
				camera.rotationX = 90;
			}
			else if(camera.rotationX < -90)
			{
				camera.rotationX = -90;
			}
			if(camera.focus > 1000)
			{
				camera.focus = 1000;
			}
			else if(camera.focus < 300)
			{
				camera.focus = 300;
			}
			// Render
			renderer.renderScene(scene,camera,container)
		}
		/**
		 *内存释放函数 
		 * 
		 */		
		public function clear():void
		{
			if(scene != null)
			{
				if(this.contains(this.container))
				{
					this.removeChild(this.container);
				}
				while(this.numChildren > 0)
				{
					this.removeChildAt(0);
				}
				scene.removeChild(cube);
			
				var tempMaterial:BitmapMaterial = cube.materials.removeMaterialByName("front") as BitmapMaterial;
				tempMaterial.destroy();

				tempMaterial = cube.materials.removeMaterialByName("back") as BitmapMaterial;
			
				tempMaterial.destroy();
			
				tempMaterial = cube.materials.removeMaterialByName("left") as BitmapMaterial;
			
				tempMaterial.destroy();
			
				tempMaterial = cube.materials.removeMaterialByName("top") as BitmapMaterial;
			
				tempMaterial.destroy();
			
				tempMaterial = cube.materials.removeMaterialByName("bottom") as BitmapMaterial;
			
				tempMaterial.destroy();
			
				tempMaterial = cube.materials.removeMaterialByName("right") as BitmapMaterial;
			
				tempMaterial.destroy();
			
				cube.destroy()
				cube = null;
				
				if(this.parentSprite != null)
				{
					this.parentSprite.removeChild(mapLoader);
				}
				mapLoader.unload();
				mapLoader.clear();
				mapLoader = null;
				var tempLength:uint = bitmapArray.length;
				for(var i:int = 0; i< tempLength;i++)
				{
					var tempContainer:LoaderModel = bitmapArray[i];
					if(tempContainer != null)
					{
						tempContainer.unload();
						tempContainer.clear();
					}
				}
				bitmapArray.splice(0);
				bitmapArray = null;
				
				this.removeEventListener(MouseEvent.MOUSE_DOWN,downHnadle);
				if(this.parentSprite != null)
				{
					this.parentSprite.removeEventListener(MouseEvent.MOUSE_UP,upHnadle);
					this.parentSprite.removeEventListener(MouseEvent.MOUSE_WHEEL,wheelHnadle);
			
					if(this.parentSprite.hasEventListener(MouseEvent.MOUSE_MOVE))
					{
						this.parentSprite.removeEventListener( MouseEvent.MOUSE_MOVE, loop );
					}
				}
				this.parentSprite = null;
				container.destroy();
				container = null;
				// destroy scene
				scene = null;

				// destroy camera
				camera = null;
			
				renderer.destroy();
				renderer = null;
			}
		}
	}
}